package cn.pdy.try_method.jdk.java.Collection;

import java.util.SortedSet;
import java.util.TreeSet;

/**
 * Set 与 Collection基本相同,没有提供额外的方法
 * Set 里的元素不允许重复
 * HashSet ,TreeSet ,EnumSet 实现类
 */
public class SetTest {
    /*
        HashSet 是Set接口的典型实现类
        HashSet按Hash算法来存储集合中的元素, 因此具有良好的存取和查找性能
        无序, 非线程安全, 元素值可以是null

        当向HashSet集合中存入一个元素时, 会调用该对象的HashCode()方法来得到该对象的HashCode值
        然后根据这个值决定该对象在HashSet中的存储位置
        判断两个元素是否相等的标准是 equals相等且hashCode也相等
        一般情况下,如果两个对象通过equals比较相等,则hashCode也应该相同

        hash(哈希,散列)算法:
            该算法的功能是,能保证快速查找被检索的对象,hash算法的价值在于速度.
            需要查询集合中某个元素时, Hash算法可以直接根据该元素的hashcode值来计算出元素的存储位置, 从而快速定位.
            为啥不直接用数组? 数组长度固定,索引连续.

         hashset 中每个能存储元素的'槽位'(slot通常称为'桶'(bucket),
         如果有多个元素的hashcode相同,equals却是false, 就需要在一个桶里放多个元素,这样会导致性能下降
     */

    /*
        LinkedHashSet --> HashSet 的子类
        该集合也是根据元素的hashcode来决定元素的存储位置, 但它同时使用链表维护元素的次序
        这样使得元素看起来是以插入的顺序保存的
     */

    /*
        TreeSet --> SortedSet 的实现类 ,提供了几个额外的方法
        可以确保集合元素处于排序状态, 默认根据元素实际值的自然顺序升序排序
        TreeSet 采用红黑树的数据结构来存储集合元素, 支持两种排序方法, 自然排序和定制排序

        TreeSet会调用集合元素的 CompareTo(Object o) 方法来比较元素之间的大小相等关系,如果compareTo相等,则不会添加
        Java提供了一个 Comparable 接口,定义了一个CompareTo(Object o)方法, 实现该接口的类必须实现该方法, 然后就可以比较大小了
        一些常用类已经实现了该接口并提供了比较大小的标准: BigDecimal,BigInteger,Character,Boolean(true>false),String,Date,Time

        如果试图把一个对象添加到TreeSet,则该对象的类必须实现Comparable接口,否则会抛出异常
        向TreeSet中添加的应该是同一个类的对象,否则也会引发类型转换异常,(因为被添加的元素会与其他元素进行比较)
     */
    public void treeSetTest(){
        TreeSet ts = new TreeSet();
        ts.comparator(); // 如果treeset采用了定制排序, 则该方法返回定制拍讯所使用的比较器, 如采用自然排序, 返回null
        ts.first();
        ts.last();
        ts.lower(new Object()); // 返回集合中位于指定元素之前的元素
        ts.higher(new Object()); // 返回集合中位于指定元素之后的元素
        // ----截取子集的方法----
        SortedSet sortedSet = ts.subSet(new Object(), new Object()); // 返回此set的子集, 范围从 fromElement 到 toElement
        SortedSet sortedSet1 = ts.headSet(new Object()); // 返回此set的子集, 由小于toElement的元素组成
        SortedSet sortedSet2 = ts.tailSet(new Object()); // 返回此set的子集, 由大于或等于fromElement的元素组成
    }

    /*
        EnumSet --> 专门为枚举类设计的集合类
        在内部以位向量的形式存储,有序
        不允许null
        不能用构造器来创建实例
     */

    /*
        各Set实现类的性能分析:
            HashSet 的性能总是比 TreeSet 好, 因为TreeSet需要额外的红黑树算法来维护集合元素的次序.
            只有当需要一个保持排序的Set时, 才应该使用TreeSet
            LinkedHashSet 的插入,删除操作比 HashSet 慢, 但是由于有了链表, 遍历会更快
            EnumSet 是所有实现类中性能最好的, 但它只能保存同一个枚举类的枚举值作为集合元素
     */

}
